home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / tracebackCode / traceback.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  2.6 KB  |  110 lines

  1. /* 
  2.  *  Subject: Re: Wanted: traceback subroutine
  3.  *  Newsgroups: comp.sys.sgi
  4.  *  Summary: Another code example of traceback
  5.  *  
  6.  *  This very simplified traceback code relies on /usr/lib/libexc.a.
  7.  *  Compile and run the sample with:
  8.  *  (Sample run)
  9.  *  #cc  myfile.c traceback.c -lexc  ;  ./a.out
  10.  *  here
  11.  *  0040023c printStackTraceback
  12.  *  00400264 c
  13.  *  00400284 static procedure (no name)
  14.  *  004001ec main
  15.  *  done
  16.  *  
  17.  *  While it works for me, it is unsupported code. No warrantee!!
  18.  *  
  19.  *  The data used by this program is created by ld(1) and makes the
  20.  *  initialized-data portion of your program larger.
  21.  *  
  22.  */
  23. /* 
  24.       Do not forget to add -lexc to the command line.
  25.  
  26.     Public Domain.   Enjoy!
  27.     Use at your own risk. No warrantee of any kind.
  28.     
  29.     Documentation : /usr/include/exception.h
  30.     Original paper: A RISC Approach to Runtime Exceptions
  31.             Mark Himelstein, Steven Correll, Kevin Enderby
  32.             Page 239
  33.             Proceedings, Summer USENIX 1988. San Francisco
  34.     
  35. */
  36.  
  37. #include <stdio.h>
  38. #include <exception.h>
  39. #include <a.out.h>
  40. #include <setjmp.h>
  41. #define    MAX_PCS        1000
  42. static unsigned int m_stackdepth = MAX_PCS;    /* how deep to log stack */
  43.  
  44.  
  45. #define    LOW_TEXT    0x00010000
  46. #define    HI_TEXT        0x10000000
  47. static int savepcs(char** pcs,RPDR **pdrp, int numpcs, int skip)
  48. {
  49.     int slot = 0;
  50.     jmp_buf jb;
  51.     unsigned long pc;
  52.     unsigned long* sp;
  53.  
  54.     setjmp(jb);
  55.     pc = jb[JB_PC];
  56.     sp = (unsigned long*) jb[JB_SP];
  57.  
  58.     /* walk up stack frame and save the pcs */
  59.     while (slot < numpcs) {
  60.     unsigned long frameoffset, framesize;
  61.     RPDR* p = find_rpd(pc); /* /usr/lib/libexc.a call */
  62.     if (!p) {
  63.         /* this can't happen, right? */
  64.         break;
  65.     }
  66.  
  67.     /* lets here it for misnamed data structures */
  68.     frameoffset = p->regoffset;
  69.     framesize = p->frameoffset;
  70.  
  71.     /* back up to previous frame */
  72.     sp = (unsigned long*) ((unsigned char*)sp + framesize);
  73.  
  74.     /* fetch return pc in current frame */
  75.     pc = sp[frameoffset>>2];
  76.     if ((pc <= LOW_TEXT) || (pc >= HI_TEXT)) {
  77.         /* pc is garbage.  stop looping */
  78.         break;
  79.     }
  80.  
  81.     /* record pc, unless we are still skipping frames */
  82.     if (skip) {
  83.         --skip;
  84.     } else {
  85.         pcs[slot] = (char*) pc;
  86.         pdrp[slot] =  p;
  87.         ++slot;
  88.     }
  89.     }
  90.     return slot;
  91. }
  92. /* number of stack frames to skip before recording */
  93. #define    SKIP    1
  94.  
  95. void printStackTraceback(FILE* fp)
  96. {
  97.     char* pcs[MAX_PCS];
  98.     RPDR* m_pdr_cache[MAX_PCS];
  99.     int numpcs;
  100.     int i;
  101.  
  102.     numpcs = savepcs(&pcs[0],m_pdr_cache, m_stackdepth, SKIP);
  103.     for (i = 0; i < numpcs; i++) {
  104.     RPDR *p;
  105.     p = m_pdr_cache[i];
  106.         (void)fprintf(fp, "%08x %s\n", pcs[i],(p && p->irpss != issNil)?
  107.         &_procedure_string_table[p->irpss] : "(unknown)");
  108.     }
  109. }
  110.